package com.htfyun.ft.fragment.factory;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;

import com.htfyun.ft.R;
import com.htfyun.ft.utils.DebugLog;
import com.htfyun.ft.utils.FileReadWrite;
import com.htfyun.ft.utils.executor.AppExecutors;
import com.htfyun.serialport.utils.UsefulUtil;

import androidx.annotation.Nullable;

public class FragmentLightSensor extends FactoryBaseFragment {

    private TextView txtReportValue;
    private TextView txtRawValue;
    private TextView txtMaxMinValue;

    private SensorManager sensorManager;
    private SensorEventListener sensorEventListener;
    private Sensor lightSensor;

    private static final float LIGHT_SENSOR_MIN_LUX_CHANGED = (float) 2000.0f;
    private float   mLuxValueMin = 0;
    private float   mLuxValueMax = 0;

    private final static String PATH_RAW_VALUE = "/sys/class/htfyun-ls/sensor_value";
    private final static String PATH_REPORT_INDEX = "/sys/class/htfyun-ls/report_index";

    private Context mContext;

    private volatile boolean isInvisible =  true;

    @Override
    protected int getLayoutRes() {
        return R.layout.fragment_factory_light_sensor;
    }

    @Override
    protected void onInitView(@Nullable Bundle savedInstanceState) {
        super.onInitView(savedInstanceState);

        mContext = getContext();

        TextView txtTips = (TextView) findViewById(R.id.txtTips);
        if (txtTips != null) {
            txtTips.setText(getString(R.string.light_sensor_tips, LIGHT_SENSOR_MIN_LUX_CHANGED));
        }

        txtReportValue = (TextView) findViewById(R.id.txtReportValue);
        txtRawValue = (TextView) findViewById(R.id.txtRawValue);
        txtMaxMinValue = (TextView) findViewById(R.id.txtMaxMinValue);

        sensorManager = mContext.getSystemService(SensorManager.class);
        lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);

        sensorEventListener = new MySensorListener();

        setBtnPassVisibility(View.GONE);
    }


    @Override
    protected void onVisible() {
        super.onVisible();

        isInvisible = false;

        mLuxValueMin = Float.MAX_VALUE;
        mLuxValueMax = Float.MIN_VALUE;

        registerListener();

        if (!isInvisible) getHandler().sendEmptyMessage(MSG_READ_RAW);

    }

    @Override
    protected void onInvisible() {
        super.onInvisible();

        isInvisible = true;

        unregisterListener();

        getHandler().removeMessages(MSG_READ_RAW_VALUE_OVER);
        getHandler().removeMessages(MSG_READ_RAW);

    }

    private volatile boolean isRegistered = false;

    private synchronized void registerListener() {
        if (isRegistered) {
            return;
        }
        isRegistered = true;

        sensorManager.registerListener(sensorEventListener, lightSensor, SensorManager.SENSOR_DELAY_NORMAL);

        DebugLog.e("registerListener");
    }

    private synchronized void unregisterListener() {
        if (!isRegistered) {
            return;
        }
        isRegistered = false;
        sensorManager.unregisterListener(sensorEventListener);

        DebugLog.e("unregisterListener");

    }


    private void updateTxtReportValue(int value) {
        String text = txtReportValue.getText().toString();
        if (text.length() > 200) {
            text = "";
        }

        txtReportValue.setText(getString(R.string.light_sensor_report_value, text, value));

    }

    private void updateTxtRawValue(int lux, int index) {
        String text = txtRawValue.getText().toString();
        if (text.length() > 200) {
            text = "";
        }

        txtRawValue.setText(getString(R.string.light_sensor_raw_value, text, lux, index));

    }

    private Runnable readRawValueRunnable = new Runnable() {
        @Override
        public void run() {

            String valueString = FileReadWrite.readFileByLines(PATH_RAW_VALUE);
            String indexString = FileReadWrite.readFileByLines(PATH_REPORT_INDEX);
            if (TextUtils.isEmpty(valueString) || TextUtils.isEmpty(indexString)) {
                return;
            }

            if (UsefulUtil.isNumeric(valueString) && UsefulUtil.isNumeric(indexString)) {
                int value = Integer.decode(valueString);
                int index = Integer.decode(indexString);
                if (!isInvisible) {
                    getHandler().obtainMessage(MSG_READ_RAW_VALUE_OVER, value, index).sendToTarget();
                }
            }
        }
    };


    private final class MySensorListener implements SensorEventListener {

        @Override
        public void onSensorChanged(SensorEvent event) {

            if (event.sensor.getType() != Sensor.TYPE_LIGHT) {
                return;
            }

            //获取光线强度
            float lux = event.values[0];

            if (lux < mLuxValueMin) {
                mLuxValueMin = lux;
            }
            if (lux > mLuxValueMax) {
                mLuxValueMax = lux;
            }
            txtMaxMinValue.setText(getString(R.string.light_sensor_max_min_value, mLuxValueMax, mLuxValueMin, (mLuxValueMax - mLuxValueMin)));

            if (mLuxValueMax - mLuxValueMin > LIGHT_SENSOR_MIN_LUX_CHANGED) {
                delayAutoPass();
            }

            updateTxtReportValue((int)lux);

        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {

        }
    }

    private final static int MSG_READ_RAW = 1000;
    private final static int PERIOD_READ_RAW = 2000;

    private final static int MSG_READ_RAW_VALUE_OVER = 1001;


    @Override
    protected void handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_READ_RAW:
                AppExecutors.runOnIoThread(readRawValueRunnable);
                if (!isInvisible) {
                    getHandler().sendEmptyMessageDelayed(msg.what, PERIOD_READ_RAW);
                }
                break;
            case MSG_READ_RAW_VALUE_OVER:
                updateTxtRawValue(msg.arg1, msg.arg2);
                break;
        }
    }
}
